<template>
  <div
    class="g-table"
    :style="{
      height: tHeight,
    }"
  >
    <div class="g-table_header">
      <div
        v-if="number"
        class="g-table_header_item"
        :style="{
          width: '50px',
          flex: 'none',
          color: thColor,
          textAlign: 'center',
        }"
      >
        <span>序号</span>
      </div>
      <div
        v-for="(th, k) in columns"
        :key="k"
        class="g-table_header_item"
        :style="{
          width: th.width ? th.width + 'px' : 'auto',
          flex: th.width ? 'none' : 1,
          color: thColor,
          textAlign: th.align ? th.align : 'center',
        }"
        @click="clickTh(th, k)"
      >
        <span>{{ th.label || "" }}</span>
      </div>
    </div>
    <div
      :id="id + '_table_body'"
      class="g-table_body"
      @mouseenter="pauseScroll"
      @mouseleave="resumeScroll"
      @wheel.prevent="handleScroll"
    >
      <div
        v-if="data.length != 0"
        :id="id + '_table_body_box'"
        :style="{ transform: `translateY(-${scrollPosition}px)` }"
      >
        <div
          v-for="(tr, k) in data"
          :key="k"
          :class="['g-table_body_item', hover ? 'hover' : '']"
          @click="clickRow(tr, k)"
        >
          <div
            v-if="number"
            class="g-table_body_item_cell"
            :style="{
              width: '50px',
              flex: 'none',
              color: '#C5E0FE',
              textAlign: 'center',
            }"
          >
            {{ k + 1 }}
          </div>
          <div
            v-for="(td, i) in columns"
            :key="i"
            class="g-table_body_item_cell"
            :class="checkWidth(td.scroll, id + '_table_body_box_' + k + '_' + i)"
            :style="{
              width: td.width ? td.width + 'px' : 'auto',
              flex: td.width ? 'none' : 1,
              textAlign: td.align ? td.align : 'center',
            }"
          >
            <div
              :id="id + '_table_body_box_' + k + '_' + i"
              :style="checkColor(tr, td, id + '_table_body_box_' + k + '_' + i)"
            >
              {{ tr[td.prop] || defaultText(tr, td) || "-" }}
            </div>
          </div>
        </div>
      </div>
      <div v-else class="g-table_body_empty">暂无数据</div>
    </div>
    <div v-if="fixeds.length != 0" class="g-table_fixed">
      <div
        v-for="(tr, k) in fixeds"
        :key="k"
        class="g-table_body_item top-up"
        @click="clickRow(tr, k)"
      >
        <div
          v-if="number"
          class="g-table_body_item_cell"
          :style="{
            width: '50px',
            flex: 'none',
            color: '#FEC5C6',
            textAlign: 'center',
          }"
        >
          {{ k + 1 }}
        </div>
        <div
          v-for="(td, i) in columns"
          :key="i"
          class="g-table_body_item_cell"
          :class="checkWidth(td.scroll, id + '_table_fixed_box_' + k + '_' + i)"
          :style="{
            width: td.width ? td.width + 'px' : 'auto',
            flex: td.width ? 'none' : 1,
            textAlign: td.align ? td.align : 'center',
          }"
        >
          <div :id="id + '_table_fixed_box_' + k + '_' + i" style="color: #fec5c6">
            {{ tr[td.prop] || defaultText(tr, td) || "-" }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "g-table",
  props: {
    /**
     * 表格唯一id
     */
    id: {
      type: [String, Number],
      default: Date.now(),
    },
    /**
     * 表格滚动速度
     * 默认为0不滚动
     * */
    speed: {
      type: [Number, String],
      default: 0,
    },
    /**
     * 表格列
     * label: 列名
     * width: 列宽
     * color: 列颜色 function string
     * scroll : 列是否滚动 默认true
     * align: 列对齐方式
     * prop: 列字段（需与data中字段一致）
     * default: 列默认值
     */
    columns: {
      type: Array,
      default: () => [],
    },
    /** 表格数据 */
    data: {
      type: Array,
      default: () => [],
    },
    // 置顶行数据
    fixeds: {
      type: Array,
      default: () => [],
    },
    /** 表格高度 */
    height: {
      type: [Number, String],
      default: "auto",
    },
    /** 显示序号 */
    number: {
      type: Boolean,
      default: false,
    },
    /** 表头颜色 */
    thColor: {
      type: String,
      default: "#9ac6f6",
    },
    /** 显示行悬浮效果 */
    hover: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      tHeight: "", // 表格高度
      scrollPosition: 0, // 滚动位置
      scrollInterval: [], // 定时器
    };
  },
  watch: {
    data: {
      handler() {
        this.clearScrollTimer();
        if (typeof Number(this.speed) === "number" && this.speed > 0) {
          this.$nextTick(() => {
            this.startScroll(this.id + "_table_body", this.id + "_table_body_box");
          });
        }
      },
    },
  },
  mounted() {
    this.calculateHeight();
  },
  destroyed() {
    this.clearScrollTimer();
  },
  methods: {
    // 计算表格高度
    calculateHeight() {
      let h = this.height;
      if (typeof h === "string") {
        const result = h.match(/\d+/);
        h = result ? Number(result[0]) + "px" : "auto";
      } else if (typeof h === "number") {
        h = h + "px";
      } else {
        h = "auto";
      }
      this.tHeight = h;
    },
    // 开始滚动
    startScroll(pid, id) {
      let timer = setInterval(() => {
        let table = document.getElementById(id);
        if (table) {
          // 检测超过一屏 需要滚动
          let parentDom = document.getElementById(pid);
          if (parentDom.clientHeight < table.clientHeight) {
            this.scrollPosition += this.speed / 10;
            if (this.scrollPosition >= table.clientHeight) {
              this.clearScrollTimer();
              this.scrollPosition = 0;
              setTimeout(() => {
                this.startScroll(pid, id);
              }, 1000);
            }
          }
        }
      }, 30);
      this.scrollInterval.push(timer);
    },
    // 滚轮滚动
    handleScroll(e) {
      if (e.deltaY < 0) {
        this.scrollPosition = Math.max(this.scrollPosition - 20, 0);
      } else {
        this.scrollPosition += 20;
      }
    },
    // 鼠标悬浮行
    pauseScroll() {
      if (this.hover) {
        this.clearScrollTimer();
      }
    },
    // 鼠标离开行
    resumeScroll() {
      if (this.hover) {
        this.clearScrollTimer();
        this.startScroll(this.id + "_table_body", this.id + "_table_body_box");
      }
    },
    // 清除定时器
    clearScrollTimer() {
      if (this.scrollInterval.length) {
        this.scrollInterval.forEach((i) => {
          clearInterval(i);
        });
        this.scrollInterval = [];
      }
    },
    // 判断是否需要滚动
    checkWidth(scroll = true, columnId) {
      let cell = document.getElementById(columnId);
      if (cell && cell.scrollWidth > cell.clientWidth && scroll) {
        cell.classList.add("marqueeText");
      }
      if (cell && !scroll) {
        cell.classList.remove("marqueeText");
      }
    },
    // 点击表头
    clickTh(th, k) {
      if ("scroll" in th) {
        th.scroll = !th.scroll;
        this.data.forEach((i, index) => {
          this.checkWidth(th.scroll, this.id + "_table_body_box_" + index + "_" + k);
        });
        this.fixeds.forEach((i, index) => {
          this.checkWidth(th.scroll, this.id + "_table_fixed_box_" + index + "_" + k);
        });
      }
    },
    // 设置颜色
    checkColor(tr, td, id) {
      let dom = document.getElementById(id);
      if (td.color) {
        if (typeof td.color === "function") {
          let color = td.color(tr);
          return this.checkColor(tr, { color }, id);
        } else if (td.color.indexOf("linear") != -1 || td.color.indexOf("radial") != -1) {
          if (dom) {
            return {
              width: dom.scrollWidth + "px",
              color: "transparent",
              background: td.color,
              "-webkit-background-clip": "text",
              "-webkit-text-fill-color": "transparent",
            };
          }
        } else {
          if (dom) {
            return { width: dom.scrollWidth + "px", color: td.color };
          } else {
            return { color: td.color };
          }
        }
      }
      return { color: "#C5E0FE" };
    },
    // 设置默认值
    defaultText(row, td) {
      if ([null, undefined, ""].includes(td.default)) {
        return "";
      } else if (typeof td.default === "string") {
        return td.default;
      } else if (typeof td.default === "function") {
        return td.default(row, td);
      } else {
        return "";
      }
    },
    // 点击行
    clickRow(row, index) {
      if (this.hover) {
        this.$emit("row-click", row, index);
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.g-table {
  width: 100%;
  position: relative;
  &_header {
    width: 100%;
    height: 55px;
    display: flex;
    align-items: center;
    position: relative;
    &_item {
      padding: 0 10px;
      font-weight: bold;
      font-size: 18px;
    }
  }
  &_fixed {
    position: absolute;
    top: 55px;
    left: 0;
    width: 100%;
    z-index: 2;
    background-color: #0c1f30;
    max-height: calc(100% - 62px);
    overflow: hidden;
  }
  &_body {
    width: 100%;
    height: calc(100% - 63px);
    overflow-y: auto;
    &_item {
      width: 100%;
      min-height: 45px;
      display: flex;
      align-items: center;
      background: url("~@/assets/table-bg.png") no-repeat;
      background-size: 100% 100%;
      margin-bottom: 8px;
      &_cell {
        font-size: 25px;
        margin: 0 10px;
        position: relative;
        overflow: hidden;
        white-space: nowrap;
      }
    }
    &_empty {
      height: 100%;
      user-select: none;
      color: #c5e0fe;
      font-size: 19px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
}
.hover:hover {
  cursor: pointer;
  background: url("~@/assets/table-bg-hover.png") no-repeat;
  background-size: 100% 100%;
}

.top-up,
.top-up:hover {
  cursor: pointer;
  background: url("~@/assets/fixed-bg.png") no-repeat;
  background-size: 100% 100%;
}

.marqueeText {
  --speed: 10s;
  animation: scroll var(--speed) linear infinite;
}

@keyframes scroll {
  10% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-100%);
  }
}
/* 整个滚动条 */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
  display: none;
}
/* 滚动条轨道 */
::-webkit-scrollbar-track {
  background: #011554;
  border-radius: 3px;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
  background: #06c1ff;
  border-radius: 3px;
  &:hover {
    background: #039bce;
  }
}
</style>
